#ifndef SEESIONHANDLER_H
#define SEESIONHANDLER_H

#include <QObject>
#include <QtNetwork/QtNetwork>
#include <QMap>
#include <QMutexLocker>

#include "utils/logger.h"
#include "network/tlpacket.h"
#include "units/player.h"
#include "server/clientsocket.h"


namespace Handlers
{


    enum TL2CMD
    {
        Client_Login        = 0x00,
     // Server_Login        = 0x01,
        Client_Discon       = 0x02,
      //Server_Discon       = 0x03,
        Client_UserData     = 0x08,
      //Server_UserData     = 0x09,
        Client_ServerInfo   = 0x0A,
      //Server_ServerInfo   = 0x0B,
        Client_GameList     = 0x0C,
      //Server_GameList     = 0x0D,
        Client_CreateGame   = 0x0F,
      //Server_CreateGame   = 0x10,
        Client_GameState    = 0x11,
        Client_GameInfo     = 0x13,
      //Server_GameInfo     = 0x14,
        Client_ConnectPeer  = 0x15,
//      Client_FailedJoin   = 0x17,
        Client_JoinGame     = 0x1A,
        Client_LeaveGame    = 0x1B,
        Client_AccInfo      = 0x20,//0x1E,
        Client_CloseGame    = 0x25,

        Both_ping           = 0x2C,
        Client_Validatekey  = 0x2A,
      //Server_FriendList   = 0x22
      //Server_BlockedList  = 0x23
        Client_ChangeChar   = 0x25,
      //Client_AddFriend    = 0x28  28 00 05 04 61 73 6C 6B
        Both_unhandled      = 0xFF
    };

    typedef void (*PACKETHANDLER)(Packets::TLPacket* pkt, ClientSocket* tcpSocket, QObject* sender );
    class SessionHandler : public QObject
    {
    Q_OBJECT
    public:
        SessionHandler(ClientSocket* Socket);
        void InPacket(Packets::TLPacket* pkt);
        void setPlayerID(quint32 plid){ _PlId=plid; }
        quint32 getPlayerID(){ return _PlId; }
        void setSessID(quint32 sid){ _SessID=sid; }
        quint32 getSessID(){ return _SessID; }

    signals:
        void SetPlayer(Player* player);
        void SendData(QByteArray data);

    private:
        ClientSocket* _tcpSocket;
        QMap<int,PACKETHANDLER> _handlers;
        quint32 _PlId;
        quint32 _SessID;
        mutable QMutex mutex;

        //Handler functions
        static void Login(Packets::TLPacket* pkt, ClientSocket* tcpSocket, QObject* sender );
        static void UserData(Packets::TLPacket* pkt, ClientSocket* tcpSocket, QObject* sender );
        static void ServerInfo(Packets::TLPacket* pkt, ClientSocket* tcpSocket, QObject* sender );
        static void AccInfo(Packets::TLPacket* pkt, ClientSocket* tcpSocket, QObject* sender );
        static void GameList(Packets::TLPacket* pkt, ClientSocket* tcpSocket, QObject* sender );
        static void GameInfo(Packets::TLPacket* pkt, ClientSocket* tcpSocket, QObject* sender );
        static void GameState(Packets::TLPacket* pkt, ClientSocket* tcpSocket, QObject* sender );
        static void JoinGame(Packets::TLPacket* pkt, ClientSocket* tcpSocket, QObject* sender );
        static void Validatekey(Packets::TLPacket* pkt, ClientSocket* tcpSocket, QObject* sender );
        static void ConnectPeer(Packets::TLPacket* pkt, ClientSocket* tcpSocket, QObject* sender );
        static void CreateGame(Packets::TLPacket* pkt, ClientSocket* tcpSocket, QObject* sender );
        static void FriendList(Packets::TLPacket* pkt, ClientSocket* tcpSocket, QObject* sender );
        static void Ping(Packets::TLPacket* pkt, ClientSocket* tcpSocket, QObject* sender );
        static void ChangeChar(Packets::TLPacket* pkt, ClientSocket* tcpSocket, QObject* sender );
        static void Disconnect(Packets::TLPacket* pkt, ClientSocket* tcpSocket, QObject* sender );
        static void LeaveGame(Packets::TLPacket* pkt, ClientSocket* tcpSocket, QObject* sender );
        static void CloseGame(Packets::TLPacket* pkt, ClientSocket* tcpSocket, QObject* sender );
        static void Unhandled(Packets::TLPacket* pkt, ClientSocket* tcpSocket, QObject* sender );
        // helpers
        static void Send0x16(Player* src, Player* dst,quint32 sessid, quint8 flag=0);
        static void Send0x20(ClientSocket* tcpSocket);
        static void SendFList(ClientSocket* tcpSocket);
    };
}
#endif // SEESIONHANDLER_H
